home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / net / amitcp_ups10.lha / ups.c < prev    next >
C/C++ Source or Header  |  1993-10-10  |  13KB  |  689 lines

  1. #ifndef lint
  2. static char RCSid[] = "$Header: QD:ups/ups2/RCS/ups.c,v 1.8 1986/12/11 15:58:18 scooter Exp alph $";
  3. #endif
  4.  
  5. /*
  6.  * ups - user interface to the package delivery system
  7.  *
  8.  * usage: ups user@host file1 file2 ...
  9.  *
  10.  * $Author: scooter $
  11.  * $Revision: 1.8 $
  12.  * $Date: 1986/12/11 15:58:18 $
  13.  *
  14.  * $Log: ups.c,v $
  15.  * Revision 1.8  86/12/11  15:58:18  scooter
  16.  * Added alias expansion code which allows ups to follow /usr/lib/aliases.
  17.  * 
  18.  * Revision 1.7  86/09/19  18:53:15  scooter
  19.  * Added -i option for mail specification
  20.  * 
  21.  * Revision 1.6  86/09/18  15:19:45  scooter
  22.  * More fixes to the '.' problam
  23.  * 
  24.  * Revision 1.5  86/09/17  09:43:38  scooter
  25.  * Added code to do automatic renaming of "." files for delivery to
  26.  * avoid the "cannot delete" problem
  27.  * 
  28.  * Revision 1.4  85/08/21  22:27:45  scooter
  29.  * Release revision: added more complete RCS headers.
  30.  * 
  31.  */
  32.  
  33. #ifdef amigados
  34. #include "sys.h"
  35. #endif
  36.  
  37. #include <stdio.h>
  38. #include <pwd.h>
  39. #include <ndbm.h>
  40. #include <sys/wait.h>
  41. #include <sys/types.h>
  42. #include <sys/stat.h>
  43. #include <sys/socket.h>
  44. #include <sys/file.h>
  45. #include <netinet/in.h>
  46. #include <netdb.h>
  47. #include <ctype.h>
  48.  
  49. #ifdef amigados
  50. #include "ups_protos.h"
  51. #endif
  52.  
  53. #define    LS "/bin/ls"
  54.  
  55. struct    passwd *getpwuid();
  56. FILE     *fopen();
  57. int    rem;
  58. int    qflg = 0;
  59. int    iflg = 0;
  60. int    on   = 1;
  61. char    buffer[BUFSIZ*5];
  62. char    mbuffer[BUFSIZ*4];
  63.  
  64. struct    user_list {
  65.     char    *u_user;
  66.     char    *u_host;
  67.     struct    user_list *u_next;
  68. };
  69.  
  70. #ifdef KR
  71. main(argc, argv)
  72. char **argv;
  73. int argc;
  74. #else
  75. int main(int argc, char **argv)
  76. #endif
  77. {
  78.     char    myhost[BUFSIZ];
  79.     int    file;
  80.     int    ret;
  81. #ifdef amigados
  82.     char    *user,*host,*tmp;
  83. #else
  84.     char    *user,*host,*tmp,*rindex(),*index();
  85. #endif
  86.     struct    passwd *mypwent;
  87. #ifdef amigados
  88.     struct    user_list *u_top, *alias_expand();
  89.     struct      user_list dummy_user;
  90. #else
  91.     struct    user_list *u_list,*u_top, *alias_expand();
  92. #endif
  93. #ifdef amigados
  94.     if(1)
  95.     {
  96.     char *env;
  97.         
  98.     env = getenv("HOSTNAME");
  99.     if(!env)
  100.     {
  101.         fprintf(stderr, "HOSTNAME not set\n");
  102.         exit(1);
  103.     }
  104.     strncpy(myhost, env, BUFSIZ);
  105.     env = getenv("USERNAME");
  106.     if(!env)
  107.     {
  108.         fprintf(stderr, "USERNAME not set\n");
  109.         exit(1);
  110.     }
  111.     mypwent = malloc(sizeof(struct passwd));
  112.     memset(mypwent, 0, sizeof(struct passwd));
  113.     mypwent->pw_passwd = strdup("");
  114.     mypwent->pw_shell = strdup("");
  115.     mypwent->pw_name = strdup(env);
  116.     mypwent->pw_gecos = strdup("Amiga OS Power User");
  117.     }
  118. #else
  119.     gethostname(myhost,BUFSIZ);
  120.     if( (mypwent = getpwuid(getuid())) == NULL )
  121.     {
  122.     fprintf(stderr,"ups: who are you?\n");
  123.     exit(1);
  124.     }
  125. #endif
  126.     argv++;
  127.     argc--;
  128.     while (argc && *argv[0] == '-')
  129.     {
  130.     char     c;
  131.  
  132.     switch (c = argv[0][1])
  133.     {
  134.  
  135.     case 'q':
  136.         qflg++;
  137.         break;
  138.  
  139.     case 'i':
  140.         iflg++;
  141.         break;
  142.  
  143.     default:
  144.         fprintf(stderr,"ups: unknown option %c\n",c);
  145.  
  146.     }
  147.     argv++;
  148.     argc--;
  149.     }
  150.  
  151.     if (argc <= 1 || qflg)
  152.     upsread(mypwent);
  153.  
  154.     if (argc < 2) 
  155.     {
  156.     fprintf(stderr,"usage: ups user@host file1 file2 ...\n");
  157.     exit(0);
  158.     }
  159.  
  160.     /*
  161.      * Get the name of the destination user and host
  162.      */
  163.  
  164.     user = argv[0];
  165.     host = rindex(user,'@');
  166.     fprintf(stderr, "user = %s\n", user);
  167. #ifndef    ALIASES
  168.     if (host == NULL)
  169.     host = myhost;
  170.     else
  171.     *host++ = '\0';
  172.  
  173.     u_top = &dummy_user;
  174.     dummy_user.u_next = 0;
  175.     dummy_user.u_user = user;
  176.     dummy_user.u_host = host;
  177. #else
  178.     if (host != NULL)
  179.     *host++ = '\0';
  180.  
  181.     u_top = alias_expand(user,host,myhost);
  182. #endif                /* ALIASES */
  183.  
  184. #ifdef DEBUG
  185.     printf("Here we are again\n");
  186. #endif
  187.  
  188.     if (iflg)
  189.     upsgetmsg(mbuffer);
  190.     else
  191.     mbuffer[0] = '\0';
  192.  
  193.     while(u_top != NULL)
  194.     {
  195.  
  196. #ifdef    DEBUG
  197.     printf("Connecting to %s for user %s\n",u_top->u_host,u_top->u_user);
  198. #endif
  199.     rem = upsconnect(u_top->u_host); /* Connect to the server */
  200.  
  201.     /*
  202.      * Send the to name, from name, and our name
  203.      */
  204.         
  205.     tmp = index(mypwent->pw_gecos,',');
  206.     if (tmp)
  207.         *tmp = '\0';
  208.  
  209.     sprintf(buffer, "%s\n%s\n%s\n%s", u_top->u_user,
  210.         mypwent->pw_name, mypwent->pw_gecos,mbuffer);
  211.  
  212. #ifdef    DEBUG
  213.     printf("Sending: %s\n",buffer);
  214.     fflush(stdout);
  215. #endif                /* DEBUG */
  216.  
  217.     write(rem, buffer, strlen(buffer)+1);
  218.     ret = read(rem, buffer, BUFSIZ);
  219.     if (buffer[0])
  220.         problem(1);
  221.  
  222.     for (file = 1 ; file < argc ; file++)
  223.     {
  224.  
  225. #ifdef    DEBUG
  226.     printf("Sending file: %s\n",argv[file]);
  227. #endif    /* DEBUG */
  228.  
  229.     sendfile(argv[file]);
  230.     }
  231.  
  232.     sprintf(buffer, "-Done-");
  233.     write(rem, buffer, strlen(buffer)+1);
  234.     read(rem, buffer, BUFSIZ);    /* get result */
  235.     if (buffer[0])        /* problem? */
  236.     problem(1);        /* yes, go handle it */
  237.  
  238.     close(rem);
  239.     u_top = u_top->u_next;
  240.     }
  241.  
  242. }
  243.  
  244.  
  245.  
  246.  
  247. upsconnect(host)
  248. char *host;
  249. {
  250.     struct hostent *hp;
  251.     struct servent *sp;
  252.     struct    sockaddr_in sin;
  253.     int s;
  254.  
  255.     hp = gethostbyname(host);
  256.     if (hp == NULL) {
  257.         static struct hostent def;
  258.         static struct in_addr defaddr;
  259.         static char namebuf[128];
  260. #ifndef amigados
  261.         int inet_addr();
  262. #endif
  263.  
  264.         defaddr.s_addr = inet_addr(host);
  265.         if (defaddr.s_addr == -1) {
  266.             printf("unknown host: %s\n", host);
  267.             exit(1);
  268.         }
  269.         strcpy(namebuf, host);
  270.         def.h_name = namebuf;
  271.         def.h_addr = (char *)&defaddr;
  272.         def.h_length = sizeof (struct in_addr);
  273.         def.h_addrtype = AF_INET;
  274.         def.h_aliases = 0;
  275.         hp = &def;
  276.     }
  277.     sp = getservbyname("ups", "tcp");
  278.     if (sp == 0) {
  279.         fprintf(stderr,"tcp/ups: unknown service\n");
  280.         exit(1);
  281.     }
  282.     sin.sin_family = hp->h_addrtype;
  283.     bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
  284.     sin.sin_port = sp->s_port;
  285.     s = socket(hp->h_addrtype, SOCK_STREAM, 0);
  286.     if (s < 0) {
  287.         fflush(stderr);
  288.         perror("ups (socket)");
  289.         exit(1);
  290.     }
  291.     setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,&on,sizeof(on));
  292. #ifdef    DEBUG
  293.     setsockopt(s,SOL_SOCKET,SO_DEBUG,&on,sizeof(on));
  294. #endif    /* DEBUG */
  295.     if (connect(s, (char *)&sin, sizeof (sin)) < 0) {
  296.         fflush(stderr);
  297.         perror("ups (connect)");
  298.         close(s);
  299.         exit(1);
  300.     }
  301.     return(s);
  302. }
  303.  
  304.  
  305.  
  306.  
  307. sendfile(file)
  308. char *file;
  309. {
  310.     struct    stat fstatus;
  311.     int    loc,n;
  312.     char    *tmp,*fname;
  313.  
  314.     if ( (loc = open(file,O_RDONLY)) <= 0 ) {
  315.     perror("ups (open)");
  316.     return(1);
  317.     }
  318.     if (fstat(loc, &fstatus)) {
  319.     perror("ups (fstat)");
  320.     return(1);
  321.     }
  322.  
  323.     if ((fstatus.st_mode&S_IFMT) != S_IFREG) {
  324.     switch (fstatus.st_mode&S_IFMT)
  325.     {
  326.     case S_IFDIR:
  327.         tmp = "directory";
  328.         break;
  329. #ifdef S_IFCHR
  330.     case S_IFCHR:
  331.         tmp = "character device";
  332.         break;
  333.     case S_IFBLK:
  334.         tmp = "block device";
  335.         break;
  336. #endif
  337. #ifdef S_IFLNK
  338.     case S_IFLNK:
  339.         tmp = "symbolic link";
  340.         break;
  341. #endif
  342. #ifdef S_IFSOCK
  343.     case S_IFSOCK:
  344.         tmp = "socket";
  345.         break;
  346. #endif
  347.     }
  348.  
  349.     fprintf(stderr,
  350.         "ups: %s is a %s, only regular files may be sent\n",
  351.         file,tmp);
  352.     fflush(stderr);
  353.     return(1);
  354.     }
  355.  
  356.     /*
  357.      * Send the file name
  358.      */
  359.  
  360.     /*
  361.      * First strip off the directory path
  362.      */
  363.         sprintf(buffer,"%s",file);
  364. #ifndef amigados
  365.     tmp = rindex(buffer,'/');
  366.     if (tmp)
  367.     *tmp++ = '\0';
  368.     else
  369.     tmp = buffer;
  370. #else
  371.     tmp = rindex(buffer,'/');
  372.     if (tmp)
  373.     *tmp++ = '\0';
  374.     else
  375.     {
  376.     tmp = rindex(buffer,':');
  377.     if (tmp)
  378.         *tmp++ = '\0';
  379.     else
  380.         tmp = buffer;
  381.     }
  382. #endif
  383.     fname = tmp;
  384.  
  385.     if (*tmp == '.')
  386.     {
  387.     while ( (*tmp == '.') && (*tmp != '\0') )tmp++;
  388.  
  389.     fprintf(stdout,
  390.         "WARNING: file %s has been renamed to %s for delivery\n",
  391.         fname,tmp);
  392.     }
  393.  
  394.     write(rem, tmp, strlen(tmp)+1);
  395.     read(rem, buffer, BUFSIZ);
  396.     if (buffer[0])        /* problem */
  397.     {
  398.     problem(0);
  399.     return(1);
  400.     }
  401.  
  402.     /*
  403.      * Send the file size in bytes
  404.      */
  405.  
  406.     sprintf(buffer, "%d",fstatus.st_size);
  407.     write(rem, buffer, strlen(buffer)+1);
  408.     read(rem, buffer, BUFSIZ);
  409.     if (buffer[0])        /* problem */
  410.     {
  411.     problem(0);
  412.     return(1);
  413.     }
  414.  
  415.     /*
  416.      * Send the file
  417.      */
  418.         while (n = read(loc, buffer, BUFSIZ))
  419.         write(rem, buffer, n);
  420.     close(loc);
  421.     read(rem, buffer, BUFSIZ);    /* get result */
  422.     if (buffer[0])        /* problem */
  423.     {
  424.     problem(0);
  425.     return(1);
  426.     }
  427. #ifndef amigados
  428.     sprintf(buffer, "%u", fstatus.st_mode);
  429. #else /* use unix modes for transmission*/
  430.     {
  431.     int unix_mode=0, ami_mode;
  432.     
  433.     ami_mode = fstatus.st_mode;
  434.     
  435.     if(ami_mode & 8)
  436.         unix_mode |= 0400;
  437.     if(ami_mode & 5)
  438.         unix_mode |= 0200;
  439.     if(ami_mode & 2)
  440.         unix_mode |= 0100;
  441.  
  442.     sprintf(buffer, "%u", unix_mode);
  443.     }
  444. #endif
  445.     write(rem, buffer, strlen(buffer)+1);
  446.     read(rem, buffer, BUFSIZ);    /* get result */
  447.     if (buffer[0])        /* problem */
  448.     {
  449.     problem(0);
  450.     return(1);
  451.     }
  452.     return(0);
  453. }
  454.  
  455.  
  456.  
  457. upsread(mypwent)
  458. struct    passwd *mypwent;
  459. {
  460. #ifndef amigados
  461.     union    wait status;
  462.     int    pid;
  463.     char    c;
  464. #endif
  465.     char    line[BUFSIZ],*tmp;
  466. #ifdef amigados
  467.     strmfp(buffer,UPSDIR,mypwent->pw_name);
  468. #else
  469.     sprintf(buffer,"%s/%s",UPSDIR,mypwent->pw_name);
  470. #endif
  471.     if (qflg)
  472.     {
  473.         if (!access(buffer,F_OK)) {
  474.             fprintf(stderr,
  475.                 "You have ups files awaiting you (type ups to accept delivery)\n");
  476.         }
  477.         exit(0);
  478.     }
  479.     if (access(buffer,F_OK)) {
  480.         fprintf(stderr,"Nothing waiting in ups\n");
  481.         exit(0);
  482.     }
  483.     fprintf(stdout,"\nYou have the following files awaiting delivery:\n\n");
  484. #ifdef amigados
  485.         {
  486.         char lbuf[BUFSIZ];
  487.         
  488.         sprintf(lbuf, "list %s", buffer);
  489.         system(lbuf);
  490.         }
  491. #else
  492.     if (pid = vfork())
  493.     {
  494.         wait(&status);
  495.     } else {
  496.         execl(LS,"ls","-C",buffer,(char *)0);
  497.         perror("ups (exec)");
  498.         return(0);
  499.     }
  500. #endif
  501.     fprintf(stdout,"\n");
  502.  
  503.     fprintf(stdout,
  504.         "Do you wish to accept delivery in your\n");
  505. #ifdef amigados
  506.     fprintf(stdout,
  507.         "current directory (%s)? ",
  508.         getcwd(line, BUFSIZ));
  509. #else
  510.     fprintf(stdout,
  511.         "current directory (%s)? ",
  512.         getwd(line));
  513. #endif
  514.  
  515. getinp:
  516.     if (fgets(line,BUFSIZ,stdin) == NULL) {
  517.         fprintf(stdout,"\n");
  518.         exit(0);
  519.     }
  520.  
  521.     tmp = &line[0];
  522.     while (isspace(*tmp)) tmp++;
  523.  
  524.     switch (*tmp) {
  525.     case 'y':
  526.     case 'Y':
  527. #ifndef amigados
  528.         sprintf(line,"mv -i %s/* . ; rmdir %s",buffer,buffer);
  529.         system(line);
  530. #else
  531.         sprintf(line,"copy %s/#? \"\"",buffer);
  532.         if(!system(line))
  533.         {
  534.             sprintf(line,"c:delete %s ALL FORCE",buffer);
  535.             system(line);
  536.         }
  537. #endif
  538.         exit(0);
  539.  
  540.     case 'n':
  541.     case 'N':
  542.         exit(0);
  543.  
  544.     default:
  545.         fprintf(stdout,"Please answer 'yes' or 'no': ");
  546.         goto getinp;
  547.     }
  548. }
  549.  
  550.  
  551.  
  552. /*
  553.  * problem() is called when the install demon process return a non-zero reply.
  554.  * This usually means something recognizable went wrong and we should expect
  555.  * a reason to follow. Read in the reason, output it on the terminal and die.
  556.  */
  557.  
  558. problem(die)
  559. int die;
  560. {
  561.     char buf[BUFSIZ];    /* place to read into */
  562.  
  563.     if (read(rem, buf, BUFSIZ) > 0)        /* if we have something */
  564.         fprintf(stderr, "ups: %s", buf);
  565.     if (die) {
  566.         close(rem);        /* close network channel */
  567.         exit(1);
  568.     }
  569. }
  570.  
  571. int
  572. upsgetmsg(mailbuffer)
  573. char *mailbuffer;
  574. {
  575.     int done = 0;
  576.  
  577.     fprintf(stdout,
  578.         "Enter your message followed by '.<RETURN>' or a <CTRL>D:\n");
  579.  
  580.     while (!done)
  581.     {
  582.         fprintf(stdout,"> ");
  583.         if (gets(mailbuffer) == NULL)
  584.         {
  585.             fprintf(stdout,"\n");
  586.             done++;
  587.         } else if ( (*mailbuffer == '.') && (*(mailbuffer+1) == '\0'))
  588.         {
  589.             done++;
  590.             *mailbuffer = '\0';
  591.         } else {
  592.             while(*mailbuffer != '\0')
  593.                 mailbuffer++;
  594.             *mailbuffer++ = '\n';
  595.             *mailbuffer = '\0';
  596.         }
  597.     }
  598.     fprintf(stdout,"[EOT]\n");
  599. }
  600.  
  601.  
  602.  
  603. #ifdef ALIASES
  604. struct user_list *
  605. alias_expand(user,host,myhost)
  606. char *user,*host,*myhost;
  607. {
  608. #ifndef amigados
  609.     char    *malloc();
  610. #endif
  611.     DBM    *dp;
  612.     datum    key,content;
  613.     struct    user_list *list,*top,*alloc_list();
  614.     char    *cp,*tp,*hp;
  615.  
  616.     list = top = (struct user_list *)NULL;
  617.  
  618.     if (host != NULL)
  619.         return(alloc_list(user,host));
  620.  
  621.     dp = dbm_open("/usr/lib/aliases", O_RDONLY, 0644);
  622.  
  623.     if (dp == NULL) {
  624.         if(host == NULL)
  625.             return(alloc_list(user, myhost));
  626.         else
  627.             return(alloc_list(user, host));
  628.     }
  629.  
  630.     key.dptr = user;
  631.     key.dsize = strlen(user) + 1;
  632.  
  633.     content = dbm_fetch(dp,key);
  634.     if (content.dptr == NULL)
  635.         return(alloc_list(user,myhost));
  636.     cp = content.dptr;
  637.  
  638.     while (cp != NULL)
  639.     {
  640.         tp = cp;
  641.         cp = index(cp,',');
  642.         if (cp != NULL)
  643.             *cp++ = '\0';
  644.         if (index(tp,'!')) {
  645.             fprintf(stderr,
  646.                 "ups: WARNING: cannot alias %s to %s (no ups over uucp)\n",
  647.                 user,hp);
  648.             continue;
  649.         } else if(index(tp,'|')) {
  650.             fprintf(stderr,
  651.                 "ups: WARNING: cannot alias %s to %s (no shells allowed)\n",
  652.                 user,hp);
  653.             continue;
  654.         }
  655.         hp = tp;
  656.         hp = index(tp,'@');
  657.         if (hp == NULL)
  658.             hp = myhost;
  659.         else
  660.             *hp++ = '\0';
  661.         if (top == NULL)
  662.             top = list = alloc_list(tp,hp);
  663.         else
  664.         {
  665.             list->u_next = alloc_list(tp,hp);
  666.             list = list->u_next;
  667.         }
  668.     }
  669.     return(top);
  670. }
  671. #endif
  672.  
  673. struct    user_list *alloc_list(user,host)
  674. char *user,*host;
  675. {
  676. #ifndef amigados
  677.     char *malloc();
  678. #endif
  679.     struct    user_list *list;
  680.  
  681.     list = (struct user_list *)malloc(sizeof(struct user_list));
  682.     list->u_user = malloc(strlen(user) + 1);
  683.     list->u_host = malloc(strlen(host) + 1);
  684.     strcpy(list->u_user,user);
  685.     strcpy(list->u_host,host);
  686.     list->u_next = (struct user_list *)NULL;
  687.     return(list);
  688. }
  689.